<?php


class MakeCode
{
    /**
     * 可以更换其中的顺序和字母，但是不可以包含数字零('0')
     * @var string ID转编码,给定字符序列
     */
    public static $idCodeChars = 'A,C,Y,2,H,S,F,9,4,T,G,E,W,L,5,Z,D,Q,X,8,V,7,R,P,6,M,J,B,U,K,3,N,I';

    /**
     * ID转编码
     * @param int $id 数字ID
     * @param string $divider 邀请码间隔码，因为有的邀请码是不足6位的，所以要有间隔码
     * @param int $code_min_length 最短设备码
     * @return string 字符编码
     */
    public static function id2code($id, $divider = '0', $code_min_length = 6)
    {
        $chars = explode(',', self::$idCodeChars);
        $chars_len = count($chars);
        $buf = '';
        // 最大下标
        $posMax = $chars_len - 1;
        // 将10进制的id转化为33进制的邀请码
        while (((int)($id / $chars_len)) > 0) {
            $ind = $id % $chars_len;
            $buf .= $chars[$ind];
            $id = (int)($id / $chars_len);
        }
        $buf .= $chars[(int)$id % $chars_len];
        // 反转buf字符串
        $buf = strrev($buf);
        // 补充长度
        $fixLen = $code_min_length - mb_strlen($buf, 'UTF-8');
        if ($fixLen > 0) {
            $buf .= $divider;
            for ($i = 0; $i < $fixLen - 1; $i++) {
                // 从字符序列中随机取出字符进行填充
                $buf .= $chars[random_int(0, $posMax)];
            }
        }
        return $buf;
    }

    /**
     * 编码转ID
     * @param string $code 字符编码
     * @param string $divider 邀请码间隔码，因为有的邀请码是不足6位的，所以要有间隔码
     * @return int 数字ID
     */
    public static function code2id($code, $divider = '0')
    {
        $chars = explode(',', self::$idCodeChars);
        $chars_len = count($chars);
        $code_len = mb_strlen($code, 'UTF-8');
        $id = 0;
        // 33进制转10进制
        for ($i = 0; $i < $code_len; $i++) {
            if ($code[$i] === $divider) {
                break;
            }
            $ind = 0;
            foreach ($chars as $j => $jValue) {
                if ($code[$i] === $jValue) {
                    $ind = $j;
                    break;
                }
            }
            if ($i > 0) {
                $id = $id * $chars_len + $ind;
            } else {
                $id = $ind;
            }
        }
        return $id;
    }
}